package com.czy.workflow.core.context;

import com.czy.workflow.core.annotation.TaskExecutor;
import com.czy.workflow.core.annotation.TaskExecutorMethod;
import com.czy.workflow.core.model.TaskInfo;
import com.czy.workflow.core.service.FlowService;
import com.czy.workflow.core.validator.FlowValidator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.logging.Logger;

/**
 * Created by admin on 2019/8/31.
 */
public class FlowComponentScan implements ApplicationListener<ContextRefreshedEvent> {

    private final static Logger logger = Logger.getLogger(FlowComponentScan.class.toString());

    private FlowContext flowContext;
    private ApplicationContext applicationContext;

    public FlowComponentScan(FlowContext flowContext) {
        this.flowContext = flowContext;
    }



    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        logger.info("init flow component ...");
        this.applicationContext = event.getApplicationContext();

        //初始化注解执行方法
        Map<String, Object> flowBeans = event.getApplicationContext().getBeansWithAnnotation(TaskExecutor.class);
        flowBeans.values().forEach((obj) -> {
            TaskExecutor executor = obj.getClass().getAnnotation(TaskExecutor.class);
            Method[] methods = obj.getClass().getMethods();
            flowContext.addExecutor(executor.flowCode(), obj);
            for(Method method : methods){
                TaskExecutorMethod executorMethod = method.getAnnotation(TaskExecutorMethod.class);
                Class[] types = method.getParameterTypes();
                if(executorMethod != null && types.length == 1 && types[0] == TaskInfo.class){
                    flowContext.addMethod(executor.flowCode(), executorMethod.nodeCode(), method);
                    logger.info(String.format("Mapped [%s-%s-%s-%s]", executor.flowCode(), executorMethod.nodeCode(),
                            obj.getClass().getSimpleName(), method.getName()));
                }
            }
        });

        //搜集可使用的持久层服务对象
        Map<String, FlowService> flowServiceMap = this.applicationContext.getBeansOfType(FlowService.class);
        for (FlowService serviceImpl : flowServiceMap.values()) {
            flowContext.addFlowService(serviceImpl.getClass().getSimpleName(), serviceImpl);
        }

        //搜集可使用的校验器
        Map<String, FlowValidator> flowValidatorMap = this.applicationContext.getBeansOfType(FlowValidator.class);
        for (FlowValidator validator : flowValidatorMap.values()) {
            flowContext.addFlowValidator(validator);
        }

//        flowContext.add
    }


}
